package jehc.djshi.oauth.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import jehc.djshi.common.base.BaseResult;
import jehc.djshi.common.base.CommonUtils;
import jehc.djshi.common.constant.CacheConstant;
import jehc.djshi.common.entity.ConstantEntity;
import jehc.djshi.common.entity.UpdatePasswordEntity;
import jehc.djshi.common.entity.UserParamInfo;
import jehc.djshi.common.entity.UserinfoEntity;
import jehc.djshi.common.util.*;
import jehc.djshi.log.client.service.LogsUtil;
import jehc.djshi.oauth.dao.OauthAccountDao;
import jehc.djshi.oauth.model.OauthAccount;
import jehc.djshi.oauth.model.OauthAccountType;
import jehc.djshi.oauth.model.OauthRole;
import jehc.djshi.oauth.param.OauthAccountTenantParam;
import jehc.djshi.oauth.service.*;
import jehc.djshi.common.base.BaseService;
import jehc.djshi.oauth.util.OauthUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Desc 授权中心账户
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Service
@Slf4j
public class OauthAccountServiceImpl extends BaseService implements OauthAccountService {

    @Resource
    OauthAccountDao oauthAccountDao;

    @Resource
    OauthRoleService oauthRoleService;

    @Resource
    OauthAccountTypeService oauthAccountTypeService;

    @Resource
    OauthAccountRoleService oauthAccountRoleService;

    @Resource
    OauthUtil oauthUtil;

    @Resource
    CommonUtils commonUtils;

    @Resource
    LogsUtil logsUtil;

    @Resource
    OauthAccountTenantService oauthAccountTenantService;

    /**
     * 分页
     * @param condition
     * @return
     */
    public List<OauthAccount> getOauthAccountList(Map<String,Object> condition){
        return oauthAccountDao.getOauthAccountList(condition);
    }

    /**
     * 查询对象
     * @param id
     * @return
     */
    public OauthAccount getOauthAccountById(String id){
        return oauthAccountDao.getOauthAccountById(id);
    }

    /**
     * 登录
     * @param condition
     * @return
     */
    public OauthAccount login(Map<String,Object> condition){
        if(null == condition.get("account")){
            throw new ExceptionUtil("用户名为空");
        }
        if(null == condition.get("password")){
            throw new ExceptionUtil("密码为空");
        }
        return oauthAccountDao.login(condition);
    }

    /**
     * 添加
     * @param oauthAccount
     * @return
     */
    public int addOauthAccount(OauthAccount oauthAccount){
        int i = 0;
        try {
            if(StringUtil.isEmpty(oauthAccount.getAccount())){
                throw new ExceptionUtil("未能获取到登录名");
            }
            OauthAccount account = oauthAccountDao.getSingleOauthAccount(oauthAccount.getAccount());
            if(null != account){
                throw new ExceptionUtil("登录名已存在！");
            }
            MD5 md5 = new MD5();
            oauthAccount.setPassword(md5.getMD5ofStr(CacheConstant.JEHC_CLOUD_USER_DEFAULT_PWD));
            oauthAccount.setCreateId(getXtUid());
            oauthAccount.setCreateTime(getDate());
            i = oauthAccountDao.addOauthAccount(oauthAccount);
        } catch (Exception e) {
            throw new ExceptionUtil(e.getMessage(),e.getCause());
        }
        return i;
    }

    /**
     * 修改（根据动态条件）
     * @param oauthAccount
     * @return
     */
    public int updateOauthAccount(OauthAccount oauthAccount){
        int i = 0;
        try {
            //如果账户存在 则判断是否重复
            if(!StringUtil.isEmpty(oauthAccount.getAccount())){
                //获取原登录名
                OauthAccount account = oauthAccountDao.getOauthAccountById(oauthAccount.getId());
                if(null != account){
                    if(!account.getAccount().equals(oauthAccount.getAccount())){ //如果登录名发生变化 则需要验证
                        if(null != oauthAccountDao.getSingleOauthAccount(oauthAccount.getAccount())){
                            throw new ExceptionUtil("登录名已存在！");
                        }
                    }
                    oauthAccount.setUpdateId(getXtUid());
                    oauthAccount.setUpdateTime(getDate());
                    i = oauthAccountDao.updateOauthAccount(oauthAccount);
                    doAccountType(account,oauthAccount.getAccountTypeId());//处理类型变更逻辑
                }
            }
        } catch (Exception e) {
            throw new ExceptionUtil(e.getMessage(),e.getCause());
        }
        return i;
    }

    /**
     * 冻结账户
     * @param oauthAccount
     * @return
     */
    public int freezeAccount(OauthAccount oauthAccount){
        int i = 0;
        try {
            i = oauthAccountDao.freezeAccount(oauthAccount);
            doAccountToken(oauthAccount);
        } catch (Exception e) {
            throw new ExceptionUtil(e.getMessage(),e.getCause());
        }
        return i;
    }

    /**
     * 查询账户集合
     * @param condition
     * @return
     */
    public List<OauthAccount> infoList(Map<String,Object> condition){
        return oauthAccountDao.infoList(condition);
    }

    /**
     * 处理账号类型
     * @param oauthAccount
     * @param newAccountTypeId
     */
    private void doAccountType(OauthAccount oauthAccount,String newAccountTypeId){
        //找出原账户类型在新账号类型中 是否减少元素，如果减少元素 则删除掉该用户原分配的角色
        List<String> changeList = new ArrayList<>();
        String oldAccountTypeId = oauthAccount.getAccountTypeId();
        if(!StringUtil.isEmpty(oldAccountTypeId)){
            String[] oldAccountTypeIdList = oldAccountTypeId.split(",");
            if(null != oldAccountTypeIdList){
                String[] newAccountTypeIdList = newAccountTypeId.split(",");
                if(!StringUtil.isEmpty(newAccountTypeId)){//如果新类型中存在记录 则判断老类型中数据在新的中是否减少 如果减少则为变更数据
                    for(int i = 0; i < oldAccountTypeIdList.length; i++){
                        String oldVal = oldAccountTypeIdList[i];
                        int existNumber = 0;
                        for(int j=0; j< newAccountTypeIdList.length;j++){
                            String newVal = newAccountTypeIdList[j];
                            if(!oldVal.equals(newVal)){
                                existNumber++;
                            }
                        }
                        if(existNumber == newAccountTypeIdList.length){
                            changeList.add(oldAccountTypeIdList[i]);
                        }
                    }
                }else{
                    //如果新类型中为空 则返回变更数据为所有原类型
                    for(int i=0; i< oldAccountTypeIdList.length;i++){
                        changeList.add(oldAccountTypeIdList[i]);
                    }
                }
            }
        }
        doAccountTypeChange(oauthAccount,changeList);//处理类型
        doTenant(oauthAccount,changeList);//处理租户
    }

    /**
     * 处理角色中该用户类型
     * @param oauthAccount
     * @param changeList
     */
    public void doAccountTypeChange(OauthAccount oauthAccount,List<String> changeList){
        if(!CollectionUtils.isEmpty(changeList)){
            StringBuilder stringBuilder = new StringBuilder();
            for(String accountTypeId:changeList){
                if(stringBuilder.length() == 0){
                    stringBuilder.append(accountTypeId);
                }else{
                    stringBuilder.append(","+accountTypeId);
                }
            }
            //根据类型查找所有子系统
            Map<String,Object> condition = new HashMap<>();
            condition.put("accountTypeId",stringBuilder.toString());
            List<OauthAccountType> oauthAccountTypes = oauthAccountTypeService.getOauthAccountTypeList(condition);

            //获取所有子系统
            StringBuilder stringBuilderSysMode = new StringBuilder();
            for(OauthAccountType oauthAccountType:oauthAccountTypes){
                if(!StringUtil.isEmpty(oauthAccountType.getSysModeId())){
                    if(stringBuilderSysMode.length() == 0){
                        stringBuilderSysMode.append(oauthAccountType.getSysModeId());
                    }else{
                        stringBuilderSysMode.append(","+oauthAccountType.getSysModeId());
                    }
                }
            }

            //获取角色
            if(!StringUtil.isEmpty(stringBuilderSysMode.toString())){
                StringBuilder stringBuilderRole = new StringBuilder();
                condition = new HashMap<>();
                condition.put("sysModeIds",stringBuilderSysMode.toString());
                List<OauthRole> oauthRoles = oauthRoleService.getOauthRoleListByCondition(condition);
                if(!CollectionUtils.isEmpty(oauthRoles)){
                    for(OauthRole oauthRole: oauthRoles){
                        if(StringUtil.isEmpty(stringBuilderRole.toString())){
                            stringBuilderRole.append(oauthRole.getId());
                        }else{
                            stringBuilderRole.append(","+oauthRole.getId());
                        }
                    }
                }


                //删除操作
                if(!StringUtil.isEmpty(stringBuilderRole.toString())){
                    condition = new HashMap<>();
                    condition.put("roleId",stringBuilderRole.toString().split(","));
                    condition.put("accountId",oauthAccount.getId());
                    oauthAccountRoleService.delBatchOauthAccountRole(condition);
                }

                //处理变更功能资源
                if(!StringUtil.isEmpty(oauthAccount.getId())){
                    String[] accountIdArray = oauthAccount.getId().split(",");
                    List<String> accountIdList = new ArrayList<>();
                    if(null != accountIdArray){
                        for(String id: accountIdArray){
                            accountIdList.add(id);
                        }
                    }
                    oauthUtil.doTokenResources(null,accountIdList);
                }
            }
        }
    }

    /**
     * 修改登录时间
     * @param oauthAccount
     */
    public void updateLoginTime(OauthAccount oauthAccount){
        oauthAccountDao.updateLoginTime(oauthAccount);
    }

    /**
     * 重置密码
     * @param userParamInfo
     * @param request
     * @return
     */
    public int restPwd(UserParamInfo userParamInfo, HttpServletRequest request){
        try {
            String accountId = userParamInfo.getAccountId();
            OauthAccount oauthAccount = null;
            if(!StringUtil.isEmpty(accountId)){
                oauthAccount = oauthAccountDao.getOauthAccountById(accountId);
            }
            if(null == oauthAccount){
                oauthAccount = oauthAccountDao.getSingleOauthAccount(userParamInfo.getAccount());
            }
            if(null == oauthAccount){
                throw new ExceptionUtil("账户不存在");
            }
            MD5 md5 = new MD5();
            ConstantEntity constantEntity = commonUtils.getXtConstantCache("XtUserinfoDefaultPwd");
            oauthAccount.setPassword(md5.getMD5ofStr(constantEntity.getValue()));
            oauthAccount.setUpdateId(getXtUid());
            oauthAccount.setUpdateTime(getDate());
            int i = updateOauthAccount(oauthAccount);
            if(i>0){
                logsUtil.aBLogs("用户控制层", "重置用户密码", "重置用户密码，用户名：【"+oauthAccount.getAccount()+"】用户姓名：【"+oauthAccount.getName()+"】成功");
            }else{
                logsUtil.aBLogs("用户控制层", "重置用户密码", "重置用户密码，用户名：【"+oauthAccount.getAccount()+"】用户姓名：【"+oauthAccount.getName()+"】失败");
            }
            return i;
        }catch (Exception e){
            throw new ExceptionUtil(e.getMessage(),e.getCause());
        }
    }

    /**
     * 修改密码
     * @param updatePasswordEntity
     * @return
     */
    public int updatePwd(UpdatePasswordEntity updatePasswordEntity){
        try {
            String accountId = updatePasswordEntity.getAccountId();
            OauthAccount oauthAccount = null;
            if(!StringUtil.isEmpty(accountId)){
                oauthAccount = oauthAccountDao.getOauthAccountById(accountId);
            }
            oauthAccount.setPassword(updatePasswordEntity.getNewPwd());
            oauthAccount.setUpdateId(getXtUid());
            oauthAccount.setUpdateTime(getDate());
            int i = updateOauthAccount(oauthAccount);
            if(i>0){
                logsUtil.aBLogs("用户控制层", "修改个人密码", "修改个人密码，用户名：【"+oauthAccount.getAccount()+"】用户姓名：【"+oauthAccount.getName()+"】成功");
            }else{
                logsUtil.aBLogs("用户控制层", "修改个人密码", "修改个人密码，用户名：【"+oauthAccount.getAccount()+"】用户姓名：【"+oauthAccount.getName()+"】失败");
            }
            return i;
        }catch (Exception e){
            throw new ExceptionUtil(e.getMessage(),e.getCause());
        }
    }

    /**
     * 同步数据
     * @param userinfoEntities
     * @return
     */
    public BaseResult sync(List<UserinfoEntity> userinfoEntities){
        BaseResult baseResult = new BaseResult();
        StringBuilder stringBuilder = new StringBuilder();
        List<OauthAccount> oauthAccounts = new ArrayList<>();
        if(!CollectionUtils.isEmpty(userinfoEntities)) {
            for (UserinfoEntity userinfoEntity : userinfoEntities) {
                try {
                    if(StringUtil.isEmpty(userinfoEntity.getId())){
                        stringBuilder.append(userinfoEntity.getName());
                        continue;
                    }
                    OauthAccount account = oauthAccountDao.getSingleOauthAccount(userinfoEntity.getAccount());
                    if(null == account){
                        account = new OauthAccount();
                        MD5 md5 = new MD5();
                        ConstantEntity constantEntity = commonUtils.getXtConstantCache("XtUserinfoDefaultPwd");
                        account.setPassword(md5.getMD5ofStr(constantEntity.getValue()));
                        account.setAccount(userinfoEntity.getAccount());
                        account.setName(userinfoEntity.getName());
                        account.setEmail(userinfoEntity.getEmail());
                        account.setId(StringUtil.isEmpty(userinfoEntity.getId())?toUUID():userinfoEntity.getId());
                        account.setAccountTypeId(userinfoEntity.getAccountTypeId());
                        account.setInfoBody(JsonUtil.toJson(userinfoEntity));
                        oauthAccountDao.addOauthAccount(account);
                    }else{
                        account.setName(userinfoEntity.getName());
                        account.setEmail(userinfoEntity.getEmail());
                        account.setInfoBody(JsonUtil.toJson(userinfoEntity));
                        if(userinfoEntity.getSync() == 1){//同步账号类型
                            if(StringUtil.isEmpty(userinfoEntity.getAccountTypeId())){
                                stringBuilder.append(userinfoEntity.getName());
                                continue;
                            }
                            account.setAccountTypeId(userinfoEntity.getAccountTypeId());//同步账号类型
                            //如果账户存在 则判断是否重复
                            if(!StringUtil.isEmpty(account.getAccount())){
                                //获取原登录名
                                if(!account.getAccount().equals(userinfoEntity.getAccount())){ //如果登录名发生变化 则需要验证
                                    if(null != oauthAccountDao.getSingleOauthAccount(userinfoEntity.getAccount())){
                                        log.info("登录名已存在{}：",account);
                                        continue;
                                    }
                                }
                                doAccountType(account,account.getAccountTypeId());//处理类型变更逻辑
                            }
                        }else{
                            //只同步登录状态的用户基本信息
                            oauthAccounts.add(account);
                        }
                        oauthAccountDao.updateOauthAccount(account);
                    }
                }catch (Exception e){
                    log.error("同步数据异常：{}",e);
                }
            }
        }
        oauthUtil.doTokenAccount(oauthAccounts);
        if(StringUtil.isEmpty(stringBuilder.toString())){
            baseResult.setMessage("同步至授权中心成功");
            return new BaseResult();
        }
        baseResult.setMessage("未能同步成功数据如下：【"+stringBuilder.toString()+"】");
        return baseResult;
    }

    /**
     *查询唯一账户
     * @param account
     * @return
     */
    public OauthAccount getSingleOauthAccount(String account){
        return oauthAccountDao.getSingleOauthAccount(account);
    }

    /**
     * 处理该冻结账户（如果已登录则将其退出）
     * @param oauthAccount
     */
    private void doAccountToken(OauthAccount oauthAccount){

        if(null == oauthAccount){
            return;
        }

        if(!StringUtil.isEmpty(oauthAccount.getId())){
            String token = oauthUtil.getTokenByAccountId(oauthAccount.getId());

            if(!StringUtil.isEmpty(token)){//删除当前登录账户的token
                oauthUtil.deleteToken(token);
            }
        }
    }

    /**
     * 处理租户
     * @param oauthAccount
     * @param changeList
     */
    private void doTenant(OauthAccount oauthAccount,List<String> changeList){
        if(CollectionUtil.isNotEmpty(changeList)){
            OauthAccountTenantParam oauthAccountTenantParam = new OauthAccountTenantParam();
            oauthAccountTenantParam.setAccount(oauthAccount.getAccount());
            oauthAccountTenantParam.setBatchAccountTypeId(changeList.toArray(new String[changeList.size()]));
            oauthAccountTenantService.delOauthAccountTenantByAccountAndType(oauthAccountTenantParam);
        }
    }

    /**
     * 修改头像
     * @param oauthAccount
     * @return
     */
    public Integer updateSmallPic(OauthAccount oauthAccount){
        return oauthAccountDao.updateSmallPic(oauthAccount);
    }
}
